<template>
  <div class="f2-toast" :class="variantClass" role="status">
    <div v-if="icon" class="f2-toast__icon">
      <v-icon v-if="isMdiIcon" :icon="icon" size="20" />
      <img v-else alt="icon" :src="icon" />
    </div>
    <div class="f2-toast__content">
      <div v-if="title" class="f2-toast__title">{{ title }}</div>
      <div v-if="message" class="f2-toast__message">{{ message }}</div>
      <div v-if="actions && actions.length > 0" class="f2-toast__actions text-right">
        <v-btn
          v-for="(a, i) in actions"
          :key="a.id || i"
          class="ml-1"
          :color="a.color || variantColor"
          size="small"
          @click="() => onAction(a)"
        >
          {{ a.label }}
        </v-btn>
      </div>
    </div>
    <button
      v-if="closeable"
      aria-label="Close"
      class="f2-toast__close flex-none"
      @click="emit('close')"
    >
      <v-icon :icon="mdiClose" size="18" />
    </button>
  </div>
</template>

<script lang="ts" setup>
import { computed } from 'vue'
import { mdiClose } from '@mdi/js'
import { NOTIFICATION_WINDOW_CHANNELS } from '~shared/ipc-topic'

const props = defineProps<{
  title?: string
  message?: string
  icon?: string
  actions?: Notify.NotificationAction[]
  closeable?: boolean
  variant?: Notify.NotificationVariant
}>()

const emit = defineEmits<{ close: [] }>()

const isMdiIcon = computed(() => props.icon?.startsWith('mdi-'))

const variantColor = computed(() => {
  switch (props.variant) {
    case 'success': {
      return 'success'
    }
    case 'warning': {
      return 'warning'
    }
    case 'error': {
      return 'error'
    }
    case 'info': {
      return 'primary'
    }
    default: {
      return typeof props.variant === 'string' ? props.variant : 'primary'
    }
  }
})

const variantClass = computed(() => `f2-toast--${props.variant || 'info'}`)

function onAction(a: Notify.NotificationAction) {
  if (a.onClick) {
    try {
      a.onClick({} as any)
      emit('close')
    } catch (error) {
      console.error('action onClick failed', error)
    }
    return
  }
  // 当在独立通知窗口中渲染时，onClick 不可序列化，使用 clickToken 通过主进程回传给发起窗口
  if (a.clickToken && typeof _pre_ !== 'undefined') {
    try {
      _pre_.ipcInvoke(NOTIFICATION_WINDOW_CHANNELS.ACTION_CLICK, { clickToken: a.clickToken })
      emit('close')
    } catch {}
  }
}
</script>

<style scoped>
.f2-toast {
  display: flex;
  align-items: flex-start;
  background: rgb(var(--v-theme-surface));
  color: rgb(var(--v-theme-on-surface));
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: 10px;
  padding: 10px 12px;
  min-width: 260px;
  max-width: 420px;
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.2);
  pointer-events: auto; /* important so container can be pointer-events:none */
  overflow: hidden;
}

.f2-toast__content {
  flex: 1;
  width: 0;
}

.f2-toast__icon img {
  width: 20px;
  height: 20px;
}

.f2-toast__title {
  font-weight: 600;
  margin-bottom: 2px;
}

.f2-toast__message {
  opacity: 0.9;
  font-size: 13px;
  line-height: 1.3;
}

.f2-toast__actions {
  margin-top: 6px;
}

.f2-toast__close {
  background: transparent;
  border: none;
  color: inherit;
  margin-left: 6px;
  cursor: pointer;
}

/* subtle left border per variant */
.f2-toast::before {
  content: '';
  width: 3px;
  height: 100%;
  border-radius: 3px 0 0 3px;
  background: var(--f2-toast-accent, currentColor);
  position: absolute;
  left: 0;
  top: 0;
}

.f2-toast {
  position: relative;
}

.f2-toast--success {
  --f2-toast-accent: rgb(var(--v-theme-success));
}

.f2-toast--warning {
  --f2-toast-accent: rgb(var(--v-theme-warning));
}

.f2-toast--error {
  --f2-toast-accent: rgb(var(--v-theme-error));
}

.f2-toast--info {
  --f2-toast-accent: rgb(var(--v-theme-primary));
}
</style>
